Web App With C & FastCGI - Path Handling & Status Code (#2)
How to read server parameters and set a status code.
Updated Dec 15, 2022

Path Handling

#include <fcgiapp.h>
#include <stdio.h>

int main() {

	printf("Hello.\n");

	FCGX_Init();
	int Socket = FCGX_OpenSocket("127.0.0.1:2016", 1024);
	FCGX_Request Request;
	FCGX_InitRequest(&Request, Socket, 0);

	while(FCGX_Accept_r(&Request) >= 0) {
		printf("Request accepted.\n");
		
		// get path
		char *Path =
			FCGX_GetParam(
				"SCRIPT_NAME",
				Request.envp
				);
		
		FCGX_FPrintF(
			Request.out,
			"Content-type: text/html\r\n\r\n"
			"<h1>Hello.</h1>"
			"<p>Path: %s</p>", // print path
			Path
			);
		FCGX_Finish_r(&Request);
	}
	
	return 0;
}
  • FCGX_GetParam gets a parameter from Request.envp (FCGX_ParamArray).

Make a request:

curl localhost/about/
<h1>Hello.</h1><p>Path: /about/</p>
#include <stdio.h>
#include <string.h> // include this
#include <fcgiapp.h>

int main() {

	printf("Hello.\n");

	FCGX_Init();
	int Socket = FCGX_OpenSocket("127.0.0.1:2016", 1024);
	FCGX_Request Request;
	FCGX_InitRequest(&Request, Socket, 0);

	while(FCGX_Accept_r(&Request) >= 0) {
		printf("Request accepted.\n");

		char *Path =
			FCGX_GetParam(
				"SCRIPT_NAME",
				Request.envp
				);
        
		// set title
		
		char Title[64] = {0};
		
		if(strcmp(Path, "/") == 0) {
			strcpy(Title, "Home");
		} else if(strcmp(Path, "/about/") == 0) {
			strcpy(Title, "About");
		} else {
			strcpy(Title, "404 Not Found");
		}
		
		FCGX_FPrintF(
			Request.out,
			"Content-type: text/html\r\n\r\n"
			"<h1>%s</h1>" // print title
			"<p>Path: %s</p>",
			Title,
			Path
			);
		FCGX_Finish_r(&Request);
	}
	
	return 0;
}

In here we use the Path variable to set a Title and use it in the response body.

Status Code

Let's send the correct status code when a non-existing page is requested.

#include <stdio.h>
#include <string.h>
#include <fcgiapp.h>

int main() {

	printf("Hello.\n");

	FCGX_Init();
	int Socket = FCGX_OpenSocket("127.0.0.1:2016", 1024);
	FCGX_Request Request;
	FCGX_InitRequest(&Request, Socket, 0);

	while(FCGX_Accept_r(&Request) >= 0) {
		printf("Request accepted.\n");

		char *Path =
			FCGX_GetParam(
				"SCRIPT_NAME",
				Request.envp
				);

		char Title[64] = {0};
		char Status[64] = "200 OK" // default status
		
		if(strcmp(Path, "/") == 0) {
			strcpy(Title, "Home");
		} else if(strcmp(Path, "/about/") == 0) {
			strcpy(Title, "About");
		} else {
			strcpy(Title, "404 Not Found");
			strcpy(Status, "404 Not Found"); // change the status for 404
		}
		
		FCGX_FPrintF(
			Request.out,
			"Status: %s\r\n" // print the status
			"Content-type: text/html\r\n\r\n"
			"<h1>%s</h1>"
			"<p>Path: %s</p>",
			Status,
			Title,
			Path
			);
		FCGX_Finish_r(&Request);
	}
	
	return 0;
}

Status is set to 404 for non-matching paths.

Use -i to include headers in the output:

curl -i localhost
HTTP/1.1 200 OK
...
curl -i localhost/sdf/
HTTP/1.1 404 Not Found
...